namespace Microsoft.Robotics.Manipulation.Visualization
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    /// <summary>
    /// Interaction logic for ArmPositionDisplayView.xaml
    /// </summary>
    public partial class ArmControlDisplayView : UserControl
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ArmControlDisplayView"/> class
        /// </summary>
        public ArmControlDisplayView()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Handler for handling the joint manual entry update button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void JointUpdate_Click(object sender, RoutedEventArgs e)
        {
            this.JointUpdateCheckBox.IsChecked = true;
        }

        /// <summary>
        /// Handler for handling the Joint manual entry sync button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void JointSync_Click(object sender, RoutedEventArgs e)
        {
            this.JointManualEntry.Text = this.CurrentJointPosition.Text;
        }

        /// <summary>
        /// Handles list box selection change
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void ListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {
            e.Handled = true;
        }

        /// <summary>
        /// Handles save button clicks
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void SavePositions_Click(object sender, RoutedEventArgs e)
        {
            this.SavePositionsCheckBox.IsChecked = true;
        }

        /// <summary>
        /// Handles load button clicks
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void LoadPositions_Click(object sender, RoutedEventArgs e)
        {
            this.LoadPositionsCheckBox.IsChecked = true;
        }

        /// <summary>
        /// Handles go to joint position button clicks
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void GoToJointPosition_Click(object sender, RoutedEventArgs e)
        {
            this.GoToJointPositionCheckBox.IsChecked = true;
        }

        /// <summary>
        /// Handles go spline button clicks
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void GoSpline_Click(object sender, RoutedEventArgs e)
        {
            this.GoToSplinePositionCheckBox.IsChecked = true;
        }

        /// <summary>
        /// Handles add/update button clicks
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void AddUpdateJointPosition_Click(object sender, RoutedEventArgs e)
        {
            this.AddUpdateJointPositionCheckBox.IsChecked = true;
        }

        /// <summary>
        /// Handles list view selection change
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            e.Handled = true;
        }

        /// <summary>
        /// Handles click on the "Add to spline" button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void AddToExtendedSpline_Click(object sender, RoutedEventArgs e)
        {
            ArmPositionDisplayModel model = (ArmPositionDisplayModel)this.DataContext;
            double time = double.NaN;
            try
            {
                time = Convert.ToDouble(this.SplineSegmentRelativeTimeTextBox.Text);
            }
            catch (FormatException)
            {
            }

            if (this.PositionsListBox.SelectedItem != null && !(double.IsInfinity(time) || double.IsNaN(time)))
            {
                model.ExtendedSplinePoints.Add(new Tuple<string, double>(this.PositionsListBox.SelectedItem.ToString(), time));
            }
        }

        /// <summary>
        /// Handles click on the "Up" button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void SplinePointUpButton_Click(object sender, RoutedEventArgs e)
        {
            ArmPositionDisplayModel model = (ArmPositionDisplayModel)this.DataContext;
            if (this.ExtendedSplineList.SelectedIndex > 0)
            {
                model.ExtendedSplinePoints.Move(this.ExtendedSplineList.SelectedIndex, this.ExtendedSplineList.SelectedIndex - 1);
            }
        }

        /// <summary>
        /// Handles click on the "Down" button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void SplinePointDownButton_Click(object sender, RoutedEventArgs e)
        {
            ArmPositionDisplayModel model = (ArmPositionDisplayModel)this.DataContext;
            if (this.ExtendedSplineList.SelectedIndex > -1 && this.ExtendedSplineList.SelectedIndex < model.ExtendedSplinePoints.Count - 1)
            {
                model.ExtendedSplinePoints.Move(this.ExtendedSplineList.SelectedIndex, this.ExtendedSplineList.SelectedIndex + 1);
            }
        } 

        /// <summary>
        /// Handles click on the "Delete" button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void SplinePointDeleteButton_Click(object sender, RoutedEventArgs e)
        {
            ArmPositionDisplayModel model = (ArmPositionDisplayModel)this.DataContext;
            if (this.ExtendedSplineList.SelectedIndex > -1)
            {
                model.ExtendedSplinePoints.RemoveAt(this.ExtendedSplineList.SelectedIndex);
            }
        } 

        /// <summary>
        /// Handles click on the "UpdateTime" button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void ChangePointTimeDuration_Click(object sender, RoutedEventArgs e)
        {
            ArmPositionDisplayModel model = (ArmPositionDisplayModel)this.DataContext;

            double time = double.NaN;
            try
            {
                time = Convert.ToDouble(this.SplineSegmentRelativeTimeUpdateTextBox.Text);
            }
            catch (FormatException)
            {
            }

            if (this.ExtendedSplineList.SelectedIndex > -1 && !(double.IsNaN(time) || double.IsInfinity(time)))
            {
                model.ExtendedSplinePoints[this.ExtendedSplineList.SelectedIndex] = new Tuple<string, double>(
                    model.ExtendedSplinePoints[this.ExtendedSplineList.SelectedIndex].Item1,
                    time);
            }
        }

        /// <summary>
        /// Handles click on the "ExecuteSpline" button
        /// </summary>
        /// <param name="sender">Element sender ignored</param>
        /// <param name="e">Action parameters ignored</param>
        private void ExecuteExtendedSplineButton_Click(object sender, RoutedEventArgs e)
        {
            ((ArmPositionDisplayModel)this.DataContext).DoExecuteExtendedSpline = true;
        }

        /// <summary>
        /// Handles click on the "Home" button
        /// </summary>
        /// <param name="sender">Element sender ignored.</param>
        /// <param name="e">Action parameters ignored.</param>
        private void HomeButton_Click(object sender, RoutedEventArgs e)
        {
            ArmPositionDisplayModel model = (ArmPositionDisplayModel)this.DataContext;
            model.GoToHomeSpeed = Convert.ToDouble(this.HomeSpeedTextBox.Text);
            model.DoGoToHome = true;
        } 
    }
}
